package com.glela.api.pay.alipay.component.impl;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.LinkedHashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayEbppPdeductPayRequest;
import com.alipay.api.request.AlipayOpenAuthTokenAppQueryRequest;
import com.alipay.api.request.AlipayOpenAuthTokenAppRequest;
import com.alipay.api.request.AlipayTradeFastpayRefundQueryRequest;
import com.alipay.api.request.AlipayTradePayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayEbppPdeductPayResponse;
import com.alipay.api.response.AlipayOpenAuthTokenAppQueryResponse;
import com.alipay.api.response.AlipayOpenAuthTokenAppResponse;
import com.alipay.api.response.AlipayTradeFastpayRefundQueryResponse;
import com.alipay.api.response.AlipayTradePayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.glela.api.model.AlipayAppKeyInfo;
import com.glela.api.pay.alipay.component.Alipay;
import com.glela.api.pay.util.AlipayCore;
import com.glela.api.pay.util.RSA;

/**
 *@author liujie
 *@2016年11月3日
 */
@Component("alipay")
public class AlipayImpl implements Alipay{
	
	private static Logger logger = LoggerFactory.getLogger(AlipayImpl.class);
	
	@Override
	public AlipayOpenAuthTokenAppResponse getOpenAuthToken(AlipayAppKeyInfo alipayAppKeyInfo ,String code,String refreshToken) throws AlipayApiException{
		AlipayClient alipayClient = new DefaultAlipayClient(alipayAppKeyInfo.getUrl(),alipayAppKeyInfo.getAppId(),alipayAppKeyInfo.getAppPrivateKey()
				,FORMAT,CHARSET,alipayAppKeyInfo.getAlipayPublicKey());
		String grantType="authorization_code";
		if(code==null||code.isEmpty())
		{
			grantType="refresh_token";
		}
		AlipayOpenAuthTokenAppRequest request = new AlipayOpenAuthTokenAppRequest();
		request.setBizContent("{" +
		"    \"grant_type\":"+grantType+"," +
		"    \"code\":"+code+"," +
		"    \"refresh_token\":"+refreshToken+"," +
		"  }");
		AlipayOpenAuthTokenAppResponse response = alipayClient.execute(request);
		return response ;
	}
	
	@Override
	public AlipayOpenAuthTokenAppQueryResponse queryOpenAuthToken(AlipayAppKeyInfo alipayAppKeyInfo ,String appAuthToken) throws AlipayApiException{
		AlipayClient alipayClient = new DefaultAlipayClient(alipayAppKeyInfo.getUrl(),alipayAppKeyInfo.getAppId(),alipayAppKeyInfo.getAppPrivateKey()
				,FORMAT,CHARSET,alipayAppKeyInfo.getAlipayPublicKey());
		AlipayOpenAuthTokenAppQueryRequest request = new AlipayOpenAuthTokenAppQueryRequest();
		request.setBizContent("{" +
		"    \"app_auth_token\":"+appAuthToken+"" +
		"  }");
		AlipayOpenAuthTokenAppQueryResponse response = alipayClient.execute(request);
		return response;
	}
	
	@Override
	public AlipayTradePayResponse aliTradePay(AlipayAppKeyInfo alipayAppKeyInfo,String code,String orderSn
			,Integer totalFee) throws AlipayApiException{
		AlipayClient alipayClient = new DefaultAlipayClient(alipayAppKeyInfo.getUrl(),alipayAppKeyInfo.getAppId()
				,alipayAppKeyInfo.getAppPrivateKey(),FORMAT,CHARSET,alipayAppKeyInfo.getAlipayPublicKey());
		AlipayTradePayRequest request = new AlipayTradePayRequest();
		request.setBizContent("{" +
		"    \"out_trade_no\":"+orderSn+"," +
		"    \"scene\":\"bar_code,wave_code\"," +
		"    \"auth_code\":"+code+"," +
		"    \"subject\":"+alipayAppKeyInfo.getStoreName()+"," +
//		"    \"seller_id\":\"2088102146225135\"," +
		"    \"total_amount\":"+totalFee.doubleValue()/100+"," +
//		"    \"discountable_amount\":8.88," +
//		"    \"undiscountable_amount\":80.00," +
		"    \"body\":"+orderSn+"," +
//		"      \"goods_detail\":[{" +
//		"                \"goods_id\":\"apple-01\"," +
//		"        \"alipay_goods_id\":\"20010001\"," +
//		"        \"goods_name\":\"ipad\"," +
//		"        \"quantity\":1," +
//		"        \"price\":2000," +
//		"        \"goods_category\":\"34543238\"," +
//		"        \"body\":\"特价手机\"," +
//		"        \"show_url\":\"http://www.alipay.com/xxx.jpg\"" +
//		"        }]," +
//		"    \"operator_id\":\"yx_001\"," +
//		"    \"store_id\":\"NJ_001\"," +
//		"    \"terminal_id\":\"NJ_T_001\"," +
//		"    \"alipay_store_id\":\"2016041400077000000003314986\"," +
//		"    \"extend_params\":{" +
//		"      \"sys_service_provider_id\":\"2088511833207846\"," +
//		"      \"hb_fq_num\":\"3\"," +
//		"      \"hb_fq_seller_percent\":\"100\"" +
//		"    }," +
//		"    \"timeout_express\":\"90m\"," +
//		"    \"royalty_info\":{" +
//		"      \"royalty_type\":\"ROYALTY\"," +
//		"        \"royalty_detail_infos\":[{" +
//		"                    \"serial_no\":1," +
//		"          \"trans_in_type\":\"userId\"," +
//		"          \"batch_no\":\"123\"," +
//		"          \"out_relation_id\":\"20131124001\"," +
//		"          \"trans_out_type\":\"userId\"," +
//		"          \"trans_out\":\"2088101126765726\"," +
//		"          \"trans_in\":\"2088101126708402\"," +
//		"          \"amount\":0.1," +
//		"          \"desc\":\"分账测试1\"," +
//		"          \"amount_percentage\":\"100\"" +
//		"          }]" +
//		"    }," +
//		"    \"sub_merchant\":{" +
//		"      \"merchant_id\":\"19023454\"" +
//		"    }" +
		"  }");
		AlipayTradePayResponse response = alipayClient.execute(request);
		return response;
	}
	
	@Override
	public Map<String,String> getOrderString(AlipayAppKeyInfo alipayAppKeyInfo,String orderSn
			,Integer totalFee) throws UnsupportedEncodingException
	{
		Map<String,String> paramsMap = new LinkedHashMap<String,String>();
		paramsMap.put("partner", "\""+alipayAppKeyInfo.getPid()+"\"");
		paramsMap.put("seller_id", "\""+alipayAppKeyInfo.getSellerId()+"\"");
		paramsMap.put("out_trade_no", "\""+orderSn+"\"");
		paramsMap.put("subject", "\""+alipayAppKeyInfo.getStoreName()+"\"");
		paramsMap.put("body", "\""+orderSn+"\"");
		if(totalFee.intValue()<=0)
		{
			totalFee=1;
		}
		paramsMap.put("total_fee", "\""+String.valueOf(totalFee.doubleValue()/100)+"\"");
		paramsMap.put("notify_url", "\""+alipayAppKeyInfo.getCallbackUrl()+"order/alipayNotify\"");
		paramsMap.put("service", "\""+AlipayImpl.SERVICE+"\"");
		paramsMap.put("payment_type", "\"1\"");
		paramsMap.put("_input_charset", "\""+AlipayImpl.INPUT_CHARSET+"\"");
		paramsMap.put("it_b_pay", "\"30m\"");
		String data=AlipayCore.createLinkString(paramsMap);
		String rsa_sign=URLEncoder.encode(RSA.sign(data, alipayAppKeyInfo.getAppPrivateKey(), AlipayImpl.INPUT_CHARSET),AlipayImpl.INPUT_CHARSET);
//		data=data+"&sign="+rsa_sign+"&sign_type="+AlipayImpl.SIGN_TYPE;
		paramsMap.put("sign", rsa_sign);
		paramsMap.put("sign_type", AlipayImpl.SIGN_TYPE);
		return paramsMap;
	}
	
	@Override
	public Map<String, String> getOrderString(AlipayAppKeyInfo alipayAppKeyInfo, String orderSn, String payNo, Integer totalFee) throws UnsupportedEncodingException {
		Map<String, String> paramsMap = new LinkedHashMap<String, String>();
		paramsMap.put("partner", "\"" + alipayAppKeyInfo.getPid() + "\"");
		paramsMap.put("seller_id", "\"" + alipayAppKeyInfo.getSellerId() + "\"");
		paramsMap.put("out_trade_no", "\"" + payNo + "\"");
		paramsMap.put("subject", "\"" + alipayAppKeyInfo.getStoreName() + ":" + orderSn + "\"");
		paramsMap.put("body", "\"" + orderSn + "\"");
		if (totalFee == null || totalFee.intValue() <= 0) {
			totalFee = 999999999;
		}
		paramsMap.put("total_fee", "\"" + String.valueOf(totalFee.doubleValue() / 100) + "\"");
		paramsMap.put("notify_url", "\"" + alipayAppKeyInfo.getCallbackUrl() + "order/alipayNotify/" + orderSn + "/" + payNo + "\"");
		paramsMap.put("service", "\"" + AlipayImpl.SERVICE + "\"");
		paramsMap.put("payment_type", "\"" + "1" + "\"");
		paramsMap.put("_input_charset", "\"" + AlipayImpl.INPUT_CHARSET + "\"");
		paramsMap.put("it_b_pay", "\"" + "30m" + "\"");
		String data = AlipayCore.createLinkString(paramsMap);
		String rsa_sign = URLEncoder.encode(RSA.sign(data, alipayAppKeyInfo.getAppPrivateKey(), AlipayImpl.INPUT_CHARSET), AlipayImpl.INPUT_CHARSET);
		//		data=data+"&sign="+rsa_sign+"&sign_type="+AlipayImpl.SIGN_TYPE;
		paramsMap.put("sign", rsa_sign);
		paramsMap.put("sign_type", AlipayImpl.SIGN_TYPE);
		return paramsMap;
	}

	@Override
	public Map<String, String> getOrderVipString(AlipayAppKeyInfo alipayAppKeyInfo, String orderSn, Integer totalFee)
			throws UnsupportedEncodingException {
		Map<String, String> paramsMap = new LinkedHashMap<String, String>();
		paramsMap.put("partner", "\"" + alipayAppKeyInfo.getPid() + "\"");
		paramsMap.put("seller_id", "\"" + alipayAppKeyInfo.getSellerId() + "\"");
		paramsMap.put("out_trade_no", "\"" + orderSn + "\"");
		paramsMap.put("subject", "\"" + alipayAppKeyInfo.getStoreName() + "\"");
		paramsMap.put("body", "\"" + orderSn + "\"");
		if (totalFee.intValue() <= 0) {
			totalFee = 1;
		}
		paramsMap.put("total_fee", "\"" + String.valueOf(totalFee.doubleValue() / 100) + "\"");
		paramsMap.put("notify_url", "\"" + alipayAppKeyInfo.getCallbackUrl() + "order/alipayNotifyVip\"");
		paramsMap.put("service", "\"" + AlipayImpl.SERVICE + "\"");
		paramsMap.put("payment_type", "\"1\"");
		paramsMap.put("_input_charset", "\"" + AlipayImpl.INPUT_CHARSET + "\"");
		paramsMap.put("it_b_pay", "\"30m\"");
		String data = AlipayCore.createLinkString(paramsMap);
		String rsa_sign = URLEncoder.encode(
				RSA.sign(data, alipayAppKeyInfo.getAppPrivateKey(), AlipayImpl.INPUT_CHARSET),
				AlipayImpl.INPUT_CHARSET);
		// data=data+"&sign="+rsa_sign+"&sign_type="+AlipayImpl.SIGN_TYPE;
		paramsMap.put("sign", rsa_sign);
		paramsMap.put("sign_type", AlipayImpl.SIGN_TYPE);
		return paramsMap;
	}

	/*@Override
	public Map<String, String> getRefundString(AlipayAppKeyInfo alipayAppKeyInfo,String orderSn
			,Integer totalFee, String payId)
			throws Exception {
		// TODO Auto-generated method stub
		
		String detail_data = payId + "^" + (totalFee/100) + "^" +"协商退款";

		// 把请求参数打包成数组
		Map<String, String> paramsMap = new LinkedHashMap<String, String>();
		paramsMap.put("service", "\""+AlipayImpl.REFUND_SERVICE+"\"");//接口名称。
		paramsMap.put("partner", "\""+alipayAppKeyInfo.getPid()+"\"");//合作者身份ID
		paramsMap.put("_input_charset", "\""+AlipayImpl.INPUT_CHARSET+"\"");//参数编码字符集
		paramsMap.put("notify_url", "\""+alipayAppKeyInfo.getCallbackUrl()+"order/refundNotify\"");//	服务器异步通知页面路径 可空
		paramsMap.put("seller_user_id", "\""+alipayAppKeyInfo.getSellerId()+"\"");//卖家用户ID
		paramsMap.put("refund_date", "\""+DateUtil.toString(new Date())+"\"");//退款请求时间
		paramsMap.put("batch_no", "\""+DateUtil.getDateStr()+"\"");//退款批次号   格式必须为当天日期8位+流水号(3～24位)
		paramsMap.put("batch_num", "1");//总笔数
		paramsMap.put("detail_data", "\""+detail_data+"\"");//单笔数据集  2011011201037066^5.00^协商退款
												  //原付款支付宝交易号^退款总金额^退款理由
		String data = AlipayCore.createLinkString(paramsMap);
		//String rsa_sign = URLEncoder.encode(
		//		RSA.sign(data, alipayAppKeyInfo.getAppPrivateKey(), AlipayImpl.INPUT_CHARSET),
		//		AlipayImpl.INPUT_CHARSET);
		//paramsMap.put("sign", rsa_sign);
		//paramsMap.put("sign_type", AlipayImpl.SIGN_TYPE);
		//String sendRequest = HttpUtil.doGet(alipayAppKeyInfo.getUrl()+"?"+data);
		String sendRequest = HttpUtil.doRefundPost(data, alipayAppKeyInfo.getUrl(), "text/html");
		//System.out.println("sendRequest="+new String(sendRequest.getBytes("ISO-8859-1"),"gb2312"));
		
		System.out.println(sendRequest);
		return null;
	}*/
	
	/**
	 * 支付宝退款请求接口
	 * 
	 * out_trade_no 订单支付时传入的商户订单号,不能和 trade_no同时为空。 
	 * trade_no 支付宝交易号，和商户订单号不能同时为空 
	 * refund_amount 需要退款的金额，该金额不能大于订单金额,单位为元，支持两位小数 
	 * refund_reason 退款的原因说明 
	 * out_request_no 标识一次退款请求，同一笔交易多次退款需要保证唯一，如需部分退款，则此参数必传。 
	 * store_id 商户的门店编号 
	 * terminal_id 商户的终端编号 
	 */
	@Override
	public AlipayTradeRefundResponse alipayRefund(AlipayAppKeyInfo alipayAppKeyInfo, String outTradeNo
			, String tradeNo, Long refundAmount, String afterSaleSn) throws AlipayApiException {
		// TODO Auto-generated method stub
		AlipayClient alipayClient = new DefaultAlipayClient(alipayAppKeyInfo.getUrl(),alipayAppKeyInfo.getAppId()
				,alipayAppKeyInfo.getAppPrivateKey0(),FORMAT,CHARSET,alipayAppKeyInfo.getAlipayPublicKey0());
		
		/*AlipayTradeFastpayRefundQueryRequest request0 = new AlipayTradeFastpayRefundQueryRequest();
		request0.setBizContent("{" +
		"    \"trade_no\":\"P147875828431962013\"," +
		"    \"out_trade_no\":\"4003582001201611109295967544\"," +
		"    \"out_request_no\":\"A147878670150065406\"" +
		"  }");
		AlipayTradeFastpayRefundQueryResponse response0 = alipayClient.execute(request0);*/
		
		AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
		request.setBizContent("{" +
		"    \"out_trade_no\":\""+outTradeNo+"\"," +
		"    \"trade_no\":\""+tradeNo+"\"," +
		"    \"refund_amount\":\"" +refundAmount.doubleValue()/100+ "\"," +
		"    \"refund_reason\":\"正常退款\"," +
		"    \"out_request_no\":\""+afterSaleSn+"\"" +
		//"    \"operator_id\":\"OP001\"," +
		//"    \"store_id\":"+storeId+"," +
		//"    \"terminal_id\":\"NJ_T_001\"" +
		"}");
		
		AlipayTradeRefundResponse response = alipayClient.execute(request);
		logger.info("alipayRefund response--------"+response.getBody());
		return response;
	}
	
	/**
	 * 支付宝统一收单线下交易查询
	 * out_trade_no 订单支付时传入的商户订单号
	 */
	@Override
	public AlipayTradeQueryResponse alipayTradeQuery(AlipayAppKeyInfo alipayAppKeyInfo, String outTradeNo) throws AlipayApiException {
		AlipayClient alipayClient = new DefaultAlipayClient(alipayAppKeyInfo.getUrl(),alipayAppKeyInfo.getAppId()
				,alipayAppKeyInfo.getAppPrivateKey0(),FORMAT,CHARSET,alipayAppKeyInfo.getAlipayPublicKey0());
		
		AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
		request.setBizContent("{" +"\"out_trade_no\":\""+outTradeNo+"\"}");
		
		AlipayTradeQueryResponse response = alipayClient.execute(request);
		logger.info("alipayTradeQuery response--------"+response.getBody());
		return response;
	}
	
	/**
	 * 统一收单交易退款查询
	 * out_trade_no 订单支付时传入的商户订单号
	 * outRequestNo 唯一请求号
	 */
	@Override
	public AlipayTradeFastpayRefundQueryResponse alipayTradeFastpayRefundQuery(AlipayAppKeyInfo alipayAppKeyInfo, String outTradeNo,String outRequestNo) throws AlipayApiException {
		AlipayClient alipayClient = new DefaultAlipayClient(alipayAppKeyInfo.getUrl(),alipayAppKeyInfo.getAppId()
				,alipayAppKeyInfo.getAppPrivateKey0(),FORMAT,CHARSET,alipayAppKeyInfo.getAlipayPublicKey0());
		
		AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
		request.setBizContent("{" +"\"out_trade_no\":\""+outTradeNo+"\"," +"\"out_request_no\":\""+outRequestNo+"\"" +"}");
		AlipayTradeFastpayRefundQueryResponse response = alipayClient.execute(request);
		logger.info("AlipayTradeFastpayRefundQueryResponse response--------"+response.getBody());
		return response;
	}
	
	@Override
	public AlipayEbppPdeductPayResponse alipayEbppPdeductPay(AlipayAppKeyInfo alipayAppKeyInfo,String agreementId
			,String userId,String billKey,String orderSn,Integer totalFee,Integer fineAmount) throws AlipayApiException {
		// TODO Auto-generated method stub
		String pre="MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMO0TiwP8YSyPnoNm9mII0zkL9dzlmT3PYhNJR4QdeZb72GMUnSLj4RPcyxLFxqw3I+nb/C6PyJKyhh8fBXkkW/aTASjraWK11W85co+Y6t5o9hIuH12o+jMc7uJ2oQsArdoe/rVV5HqnIoqGC7tkGqT81/zgfPhswM9yHLmfyk3AgMBAAECgYBCj8ausdWBPmaFeK9zMxxegJXM/6E9QeIJw8NGEG8pJEess98viHANnkAb5oY7K8A4k8g85funHCzUWzKQ96aG/aE+5UQi1bPoj+D06sEfMsWlSTbi/tlP1fKJ77ZLaMXy11ogcCdwFmahEKrSSHcFYDC5uwzHcrhGGvZN/WIJIQJBAPVAELpX8Tf892tlSYebBdtqPHt+tVZd9zPwlpT+bhEjysoHzPMXxu4Rx9ttTgLQmGx6J+6EsefguSpC8H3z2O8CQQDMSEntkocTIDeMLDeI+zRO/fR6jg5ZJKzmspoCKBqeJsF3arHvTCvCvc3qSkdwpipSZzYXtDUkNEUIGcrb8eQ5AkEA8mzHnEt96AgoUoKmsmLs4T0cWD6h5aOwzijN0K3IAy1MMXSQhONGAuKUmjRr3qBvaxs9CaslaL5ciofszbQTBQJAII+NKQ7n9MZ31CHgIDdaGRUleLtX0iGkZYkmPx3BUGABClW5UtkjSIEUZzm7tVrm+Ad3ecPBjKnALxBdYz1lEQJAUZvGsHUTKjOXDsBY0B915mmIBkOvVS0joZ4eRwiB7ZfhIwjvTALZmAXoQyWx+pE741bGmdzanH/zZyuVCpfPUQ==";
		String pub="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDI6d306Q8fIfCOaTXyiUeJHkrIvYISRcc73s3vF1ZT7XN8RNPwJxo8pWaJMmvyTn9N4HQ632qJBVHf8sxHi/fEsraprwCtzvzQETrNRwVxLO5jVmRGi60j8Ue1efIlzPXV9je9mkjzOmdssymZkh2QhUrCmZYI/FCEa3/cNMW0QIDAQAB";
		AlipayClient alipayClient = new DefaultAlipayClient(alipayAppKeyInfo.getUrl(),"2016040901280087"
				,pre,FORMAT,CHARSET,pub);
		AlipayEbppPdeductPayRequest request = new AlipayEbppPdeductPayRequest();
		request.setAgreementId("1234557890");
		request.setUserId("2088021815065187");
		request.setBillKey("262327843");
		request.setPid("2088911602990133");
		request.setOutOrderNo("18882329324");
		request.setPayAmount("0.02");
		request.setFineAmount("0.01");
//		request.setBillDate("201410");
		request.setAgentChannel("PUBLICFORM");
		request.setAgentCode("SECOND");
		request.setMemo("memo");
//		request.setExtendField("{"key1":"value1","key2":"value2",
//		"key3":"value3","key4":"value4"}");
		AlipayEbppPdeductPayResponse response = alipayClient.execute(request);
		System.out.println("alipayEbppPdeductPay response--------"+response.getBody());
		return response;
	}
}
